using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain;
using Persistent;

namespace UI.Controllers
{   
    public class GameController : Controller
    {
		private readonly IGameRepository gameRepository;

		// If  using Dependency Injection, we can delete the following constructor
        public GameController() : this(new GameRepository())
        {
        }

        public GameController(IGameRepository gameRepository)
        {
			this.gameRepository = gameRepository;
        }

        public ViewResult Index()
        {
            // we should limit this to some appropriate creteria
            var allGame = gameRepository.All;
            ICollection<Models.GameDisplay> allGames = new List<Models.GameDisplay>();

            allGame.ToList().ForEach(a => allGames.Add(Models.GameDisplay.MapToUI(a)));
            return View(allGames);
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult Details(int id)
        {
            return View(UI.Models.GameDisplay.MapToUI(gameRepository.Find(id)));
        }

        public ActionResult Create()
        {
            return View();
        } 

        [HttpPost]
        public ActionResult Create(UI.Models.GameDisplay game)
        {
            if (ModelState.IsValid)
            {
                var newGame = new Domain.Game(game.GetGameDateAndTime());
                gameRepository.InsertOrUpdate(newGame);
                gameRepository.Save();
                return RedirectToAction("Index");
            }
            else
            {
                return View();
            }
        }

        public ActionResult Publish(int id)
        {
            var game = gameRepository.Find(id);
            try
            {
                game.Publish();
                gameRepository.InsertOrUpdate(game);
                gameRepository.Save();
            }
            catch (System.ApplicationException ex)
            {
                // Need a control to display error messages
            }
            
            return RedirectToAction("Index");
        }


        public ActionResult AddPlayer(int id)
        {
            var game = gameRepository.Find(id);
            var addPlayerToGameDisplay = new UI.Models.AddPlayerToGameDisplay();
            addPlayerToGameDisplay.GameToDisplay = UI.Models.GameDisplay.MapToUI(game);
            return View(addPlayerToGameDisplay);
        }

        [HttpPost]
        public ActionResult AddPlayer(UI.Models.AddPlayerToGameDisplay addPlayerToGameDisplay)
        {
            if (ModelState.IsValid) 
            {
                Domain.Game game = null;
                try
                {
                    game = gameRepository.Find(addPlayerToGameDisplay.GameToDisplay.GameId);
                    
                    using (Persistent.PlayerRepository playerRepository = new Persistent.PlayerRepository())
                    {
                        int playerId;
                        Int32.TryParse(addPlayerToGameDisplay.SelectedPlayer, out playerId);
                        var player = playerRepository.Find(playerId);
                        game.AddPlayer(player);
                    }
                    gameRepository.InsertOrUpdate(game);
                    gameRepository.Save();
                    return RedirectToAction("Index");
                }
                catch (System.ApplicationException ex)
                {
                    addPlayerToGameDisplay.Error = ex.Message;
                    addPlayerToGameDisplay.GameToDisplay = UI.Models.GameDisplay.MapToUI(game);
                    return View(addPlayerToGameDisplay);
                }
            } 
            else 
            {                
                return View();
			}
        }

        public ActionResult Delete(int id)
        {
            return View(gameRepository.Find(id));
        }

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            gameRepository.Delete(id);
            gameRepository.Save();

            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing) {
                gameRepository.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

